//
// Copyright (C) [2020] Futurewei Technologies, Inc.
//
// FORCE-RISCV is licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
// FIT FOR A PARTICULAR PURPOSE.
// See the License for the specific language governing permissions and
// limitations under the License.
//

/*  !!! NOTICE !!!
    This file is automatically generated by the script: utils/enum_classes/create_enum_files.py
    Please do not modify this file manually.  Instead, modify the above mentioned script to re-generate this file.
*/

#include <lest/lest.hpp>
#include <Log.h>

#include <EnumsRISCV.h>
#include <GenException.h>

using text = std::string;
using namespace Force;

const lest::test specification[] = {


CASE( "tests for ERegReserveGroup" ) {

  SETUP ( "setup ERegReserveGroup" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(ERegReserveGroup_to_string(ERegReserveGroup::GPR) == "GPR");
      EXPECT(ERegReserveGroup_to_string(ERegReserveGroup::FPRSIMDR) == "FPRSIMDR");
      EXPECT(ERegReserveGroup_to_string(ERegReserveGroup::VECREG) == "VECREG");
      EXPECT(ERegReserveGroup_to_string(ERegReserveGroup::SystemRegister) == "SystemRegister");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_ERegReserveGroup("GPR") == ERegReserveGroup::GPR);
      EXPECT(string_to_ERegReserveGroup("FPRSIMDR") == ERegReserveGroup::FPRSIMDR);
      EXPECT(string_to_ERegReserveGroup("VECREG") == ERegReserveGroup::VECREG);
      EXPECT(string_to_ERegReserveGroup("SystemRegister") == ERegReserveGroup::SystemRegister);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_ERegReserveGroup("G_R"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_ERegReserveGroup("GPR", okay) == ERegReserveGroup::GPR);
      EXPECT(okay);
      EXPECT(try_string_to_ERegReserveGroup("FPRSIMDR", okay) == ERegReserveGroup::FPRSIMDR);
      EXPECT(okay);
      EXPECT(try_string_to_ERegReserveGroup("VECREG", okay) == ERegReserveGroup::VECREG);
      EXPECT(okay);
      EXPECT(try_string_to_ERegReserveGroup("SystemRegister", okay) == ERegReserveGroup::SystemRegister);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_ERegReserveGroup("G_R", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EVmRegimeType" ) {

  SETUP ( "setup EVmRegimeType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EVmRegimeType_to_string(EVmRegimeType::M) == "M");
      EXPECT(EVmRegimeType_to_string(EVmRegimeType::S) == "S");
      EXPECT(EVmRegimeType_to_string(EVmRegimeType::HS) == "HS");
      EXPECT(EVmRegimeType_to_string(EVmRegimeType::VS) == "VS");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EVmRegimeType("M") == EVmRegimeType::M);
      EXPECT(string_to_EVmRegimeType("S") == EVmRegimeType::S);
      EXPECT(string_to_EVmRegimeType("HS") == EVmRegimeType::HS);
      EXPECT(string_to_EVmRegimeType("VS") == EVmRegimeType::VS);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EVmRegimeType("_"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EVmRegimeType("M", okay) == EVmRegimeType::M);
      EXPECT(okay);
      EXPECT(try_string_to_EVmRegimeType("S", okay) == EVmRegimeType::S);
      EXPECT(okay);
      EXPECT(try_string_to_EVmRegimeType("HS", okay) == EVmRegimeType::HS);
      EXPECT(okay);
      EXPECT(try_string_to_EVmRegimeType("VS", okay) == EVmRegimeType::VS);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EVmRegimeType("_", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EMemBankType" ) {

  SETUP ( "setup EMemBankType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EMemBankType_to_string(EMemBankType::Default) == "Default");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EMemBankType("Default") == EMemBankType::Default);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EMemBankType("D_fault"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EMemBankType("Default", okay) == EMemBankType::Default);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EMemBankType("D_fault", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EVmContextParamType" ) {

  SETUP ( "setup EVmContextParamType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::MODE) == "MODE");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::MPRV) == "MPRV");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::MPP) == "MPP");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::SPP) == "SPP");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::MXR) == "MXR");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::SUM) == "SUM");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::MBE) == "MBE");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::SBE) == "SBE");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::UBE) == "UBE");
      EXPECT(EVmContextParamType_to_string(EVmContextParamType::TVM) == "TVM");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EVmContextParamType("MODE") == EVmContextParamType::MODE);
      EXPECT(string_to_EVmContextParamType("MPRV") == EVmContextParamType::MPRV);
      EXPECT(string_to_EVmContextParamType("MPP") == EVmContextParamType::MPP);
      EXPECT(string_to_EVmContextParamType("SPP") == EVmContextParamType::SPP);
      EXPECT(string_to_EVmContextParamType("MXR") == EVmContextParamType::MXR);
      EXPECT(string_to_EVmContextParamType("SUM") == EVmContextParamType::SUM);
      EXPECT(string_to_EVmContextParamType("MBE") == EVmContextParamType::MBE);
      EXPECT(string_to_EVmContextParamType("SBE") == EVmContextParamType::SBE);
      EXPECT(string_to_EVmContextParamType("UBE") == EVmContextParamType::UBE);
      EXPECT(string_to_EVmContextParamType("TVM") == EVmContextParamType::TVM);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EVmContextParamType("M_DE"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EVmContextParamType("MODE", okay) == EVmContextParamType::MODE);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("MPRV", okay) == EVmContextParamType::MPRV);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("MPP", okay) == EVmContextParamType::MPP);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("SPP", okay) == EVmContextParamType::SPP);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("MXR", okay) == EVmContextParamType::MXR);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("SUM", okay) == EVmContextParamType::SUM);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("MBE", okay) == EVmContextParamType::MBE);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("SBE", okay) == EVmContextParamType::SBE);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("UBE", okay) == EVmContextParamType::UBE);
      EXPECT(okay);
      EXPECT(try_string_to_EVmContextParamType("TVM", okay) == EVmContextParamType::TVM);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EVmContextParamType("M_DE", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EBranchConditionType" ) {

  SETUP ( "setup EBranchConditionType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BEQ) == "BEQ");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BNE) == "BNE");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BLT) == "BLT");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BLTU) == "BLTU");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BGE) == "BGE");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::BGEU) == "BGEU");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::CBEQZ) == "CBEQZ");
      EXPECT(EBranchConditionType_to_string(EBranchConditionType::CBNEZ) == "CBNEZ");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EBranchConditionType("BEQ") == EBranchConditionType::BEQ);
      EXPECT(string_to_EBranchConditionType("BNE") == EBranchConditionType::BNE);
      EXPECT(string_to_EBranchConditionType("BLT") == EBranchConditionType::BLT);
      EXPECT(string_to_EBranchConditionType("BLTU") == EBranchConditionType::BLTU);
      EXPECT(string_to_EBranchConditionType("BGE") == EBranchConditionType::BGE);
      EXPECT(string_to_EBranchConditionType("BGEU") == EBranchConditionType::BGEU);
      EXPECT(string_to_EBranchConditionType("CBEQZ") == EBranchConditionType::CBEQZ);
      EXPECT(string_to_EBranchConditionType("CBNEZ") == EBranchConditionType::CBNEZ);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EBranchConditionType("B_Q"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EBranchConditionType("BEQ", okay) == EBranchConditionType::BEQ);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("BNE", okay) == EBranchConditionType::BNE);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("BLT", okay) == EBranchConditionType::BLT);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("BLTU", okay) == EBranchConditionType::BLTU);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("BGE", okay) == EBranchConditionType::BGE);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("BGEU", okay) == EBranchConditionType::BGEU);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("CBEQZ", okay) == EBranchConditionType::CBEQZ);
      EXPECT(okay);
      EXPECT(try_string_to_EBranchConditionType("CBNEZ", okay) == EBranchConditionType::CBNEZ);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EBranchConditionType("B_Q", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EPteAttributeType" ) {

  SETUP ( "setup EPteAttributeType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::Address) == "Address");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::IGNORED) == "IGNORED");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::RES0) == "RES0");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::SystemPage) == "SystemPage");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::RSW) == "RSW");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::DA) == "DA");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::G) == "G");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::U) == "U");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::X) == "X");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::WR) == "WR");
      EXPECT(EPteAttributeType_to_string(EPteAttributeType::V) == "V");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EPteAttributeType("Address") == EPteAttributeType::Address);
      EXPECT(string_to_EPteAttributeType("IGNORED") == EPteAttributeType::IGNORED);
      EXPECT(string_to_EPteAttributeType("RES0") == EPteAttributeType::RES0);
      EXPECT(string_to_EPteAttributeType("SystemPage") == EPteAttributeType::SystemPage);
      EXPECT(string_to_EPteAttributeType("RSW") == EPteAttributeType::RSW);
      EXPECT(string_to_EPteAttributeType("DA") == EPteAttributeType::DA);
      EXPECT(string_to_EPteAttributeType("G") == EPteAttributeType::G);
      EXPECT(string_to_EPteAttributeType("U") == EPteAttributeType::U);
      EXPECT(string_to_EPteAttributeType("X") == EPteAttributeType::X);
      EXPECT(string_to_EPteAttributeType("WR") == EPteAttributeType::WR);
      EXPECT(string_to_EPteAttributeType("V") == EPteAttributeType::V);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EPteAttributeType("A_dress"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EPteAttributeType("Address", okay) == EPteAttributeType::Address);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("IGNORED", okay) == EPteAttributeType::IGNORED);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("RES0", okay) == EPteAttributeType::RES0);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("SystemPage", okay) == EPteAttributeType::SystemPage);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("RSW", okay) == EPteAttributeType::RSW);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("DA", okay) == EPteAttributeType::DA);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("G", okay) == EPteAttributeType::G);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("U", okay) == EPteAttributeType::U);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("X", okay) == EPteAttributeType::X);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("WR", okay) == EPteAttributeType::WR);
      EXPECT(okay);
      EXPECT(try_string_to_EPteAttributeType("V", okay) == EPteAttributeType::V);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EPteAttributeType("A_dress", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EPageGranuleType" ) {

  SETUP ( "setup EPageGranuleType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EPageGranuleType_to_string(EPageGranuleType::G4K) == "G4K");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EPageGranuleType("G4K") == EPageGranuleType::G4K);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EPageGranuleType("G_K"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EPageGranuleType("G4K", okay) == EPageGranuleType::G4K);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EPageGranuleType("G_K", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EPageGenBoolAttrType" ) {

  SETUP ( "setup EPageGenBoolAttrType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::FlatMap) == "FlatMap");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::InstrAddr) == "InstrAddr");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::Regulated) == "Regulated");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::ViaException) == "ViaException");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::Privileged) == "Privileged");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::Atomic) == "Atomic");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::CanAlias) == "CanAlias");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::ForceAlias) == "ForceAlias");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::ForceMemAttrs) == "ForceMemAttrs");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::ForceNewAddr) == "ForceNewAddr");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::NoDataPageFault) == "NoDataPageFault");
      EXPECT(EPageGenBoolAttrType_to_string(EPageGenBoolAttrType::NoInstrPageFault) == "NoInstrPageFault");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EPageGenBoolAttrType("FlatMap") == EPageGenBoolAttrType::FlatMap);
      EXPECT(string_to_EPageGenBoolAttrType("InstrAddr") == EPageGenBoolAttrType::InstrAddr);
      EXPECT(string_to_EPageGenBoolAttrType("Regulated") == EPageGenBoolAttrType::Regulated);
      EXPECT(string_to_EPageGenBoolAttrType("ViaException") == EPageGenBoolAttrType::ViaException);
      EXPECT(string_to_EPageGenBoolAttrType("Privileged") == EPageGenBoolAttrType::Privileged);
      EXPECT(string_to_EPageGenBoolAttrType("Atomic") == EPageGenBoolAttrType::Atomic);
      EXPECT(string_to_EPageGenBoolAttrType("CanAlias") == EPageGenBoolAttrType::CanAlias);
      EXPECT(string_to_EPageGenBoolAttrType("ForceAlias") == EPageGenBoolAttrType::ForceAlias);
      EXPECT(string_to_EPageGenBoolAttrType("ForceMemAttrs") == EPageGenBoolAttrType::ForceMemAttrs);
      EXPECT(string_to_EPageGenBoolAttrType("ForceNewAddr") == EPageGenBoolAttrType::ForceNewAddr);
      EXPECT(string_to_EPageGenBoolAttrType("NoDataPageFault") == EPageGenBoolAttrType::NoDataPageFault);
      EXPECT(string_to_EPageGenBoolAttrType("NoInstrPageFault") == EPageGenBoolAttrType::NoInstrPageFault);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EPageGenBoolAttrType("F_atMap"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EPageGenBoolAttrType("FlatMap", okay) == EPageGenBoolAttrType::FlatMap);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("InstrAddr", okay) == EPageGenBoolAttrType::InstrAddr);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("Regulated", okay) == EPageGenBoolAttrType::Regulated);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("ViaException", okay) == EPageGenBoolAttrType::ViaException);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("Privileged", okay) == EPageGenBoolAttrType::Privileged);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("Atomic", okay) == EPageGenBoolAttrType::Atomic);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("CanAlias", okay) == EPageGenBoolAttrType::CanAlias);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("ForceAlias", okay) == EPageGenBoolAttrType::ForceAlias);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("ForceMemAttrs", okay) == EPageGenBoolAttrType::ForceMemAttrs);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("ForceNewAddr", okay) == EPageGenBoolAttrType::ForceNewAddr);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("NoDataPageFault", okay) == EPageGenBoolAttrType::NoDataPageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPageGenBoolAttrType("NoInstrPageFault", okay) == EPageGenBoolAttrType::NoInstrPageFault);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EPageGenBoolAttrType("F_atMap", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EPagingExceptionType" ) {

  SETUP ( "setup EPagingExceptionType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::InstructionAccessFault) == "InstructionAccessFault");
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::LoadAccessFault) == "LoadAccessFault");
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::StoreAmoAccessFault) == "StoreAmoAccessFault");
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::InstructionPageFault) == "InstructionPageFault");
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::LoadPageFault) == "LoadPageFault");
      EXPECT(EPagingExceptionType_to_string(EPagingExceptionType::StoreAmoPageFault) == "StoreAmoPageFault");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EPagingExceptionType("InstructionAccessFault") == EPagingExceptionType::InstructionAccessFault);
      EXPECT(string_to_EPagingExceptionType("LoadAccessFault") == EPagingExceptionType::LoadAccessFault);
      EXPECT(string_to_EPagingExceptionType("StoreAmoAccessFault") == EPagingExceptionType::StoreAmoAccessFault);
      EXPECT(string_to_EPagingExceptionType("InstructionPageFault") == EPagingExceptionType::InstructionPageFault);
      EXPECT(string_to_EPagingExceptionType("LoadPageFault") == EPagingExceptionType::LoadPageFault);
      EXPECT(string_to_EPagingExceptionType("StoreAmoPageFault") == EPagingExceptionType::StoreAmoPageFault);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EPagingExceptionType("I_structionAccessFault"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EPagingExceptionType("InstructionAccessFault", okay) == EPagingExceptionType::InstructionAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPagingExceptionType("LoadAccessFault", okay) == EPagingExceptionType::LoadAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPagingExceptionType("StoreAmoAccessFault", okay) == EPagingExceptionType::StoreAmoAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPagingExceptionType("InstructionPageFault", okay) == EPagingExceptionType::InstructionPageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPagingExceptionType("LoadPageFault", okay) == EPagingExceptionType::LoadPageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EPagingExceptionType("StoreAmoPageFault", okay) == EPagingExceptionType::StoreAmoPageFault);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EPagingExceptionType("I_structionAccessFault", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EVmConstraintType" ) {

  SETUP ( "setup EVmConstraintType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::Existing) == "Existing");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::AddressError) == "AddressError");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::ReadOnly) == "ReadOnly");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::NoExecute) == "NoExecute");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::PrivilegedNoExecute) == "PrivilegedNoExecute");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::UnprivilegedNoExecute) == "UnprivilegedNoExecute");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::NoUserAccess) == "NoUserAccess");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::PageTable) == "PageTable");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::UserAccess) == "UserAccess");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::PageFault) == "PageFault");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::FlatMap) == "FlatMap");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::AccessFault) == "AccessFault");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::NoDataAccess) == "NoDataAccess");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::NotAccessed) == "NotAccessed");
      EXPECT(EVmConstraintType_to_string(EVmConstraintType::NotDirty) == "NotDirty");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EVmConstraintType("Existing") == EVmConstraintType::Existing);
      EXPECT(string_to_EVmConstraintType("AddressError") == EVmConstraintType::AddressError);
      EXPECT(string_to_EVmConstraintType("ReadOnly") == EVmConstraintType::ReadOnly);
      EXPECT(string_to_EVmConstraintType("NoExecute") == EVmConstraintType::NoExecute);
      EXPECT(string_to_EVmConstraintType("PrivilegedNoExecute") == EVmConstraintType::PrivilegedNoExecute);
      EXPECT(string_to_EVmConstraintType("UnprivilegedNoExecute") == EVmConstraintType::UnprivilegedNoExecute);
      EXPECT(string_to_EVmConstraintType("NoUserAccess") == EVmConstraintType::NoUserAccess);
      EXPECT(string_to_EVmConstraintType("PageTable") == EVmConstraintType::PageTable);
      EXPECT(string_to_EVmConstraintType("UserAccess") == EVmConstraintType::UserAccess);
      EXPECT(string_to_EVmConstraintType("PageFault") == EVmConstraintType::PageFault);
      EXPECT(string_to_EVmConstraintType("FlatMap") == EVmConstraintType::FlatMap);
      EXPECT(string_to_EVmConstraintType("AccessFault") == EVmConstraintType::AccessFault);
      EXPECT(string_to_EVmConstraintType("NoDataAccess") == EVmConstraintType::NoDataAccess);
      EXPECT(string_to_EVmConstraintType("NotAccessed") == EVmConstraintType::NotAccessed);
      EXPECT(string_to_EVmConstraintType("NotDirty") == EVmConstraintType::NotDirty);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EVmConstraintType("E_isting"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EVmConstraintType("Existing", okay) == EVmConstraintType::Existing);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("AddressError", okay) == EVmConstraintType::AddressError);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("ReadOnly", okay) == EVmConstraintType::ReadOnly);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("NoExecute", okay) == EVmConstraintType::NoExecute);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("PrivilegedNoExecute", okay) == EVmConstraintType::PrivilegedNoExecute);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("UnprivilegedNoExecute", okay) == EVmConstraintType::UnprivilegedNoExecute);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("NoUserAccess", okay) == EVmConstraintType::NoUserAccess);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("PageTable", okay) == EVmConstraintType::PageTable);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("UserAccess", okay) == EVmConstraintType::UserAccess);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("PageFault", okay) == EVmConstraintType::PageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("FlatMap", okay) == EVmConstraintType::FlatMap);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("AccessFault", okay) == EVmConstraintType::AccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("NoDataAccess", okay) == EVmConstraintType::NoDataAccess);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("NotAccessed", okay) == EVmConstraintType::NotAccessed);
      EXPECT(okay);
      EXPECT(try_string_to_EVmConstraintType("NotDirty", okay) == EVmConstraintType::NotDirty);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EVmConstraintType("E_isting", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EPrivilegeLevelType" ) {

  SETUP ( "setup EPrivilegeLevelType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EPrivilegeLevelType_to_string(EPrivilegeLevelType::U) == "U");
      EXPECT(EPrivilegeLevelType_to_string(EPrivilegeLevelType::S) == "S");
      EXPECT(EPrivilegeLevelType_to_string(EPrivilegeLevelType::H) == "H");
      EXPECT(EPrivilegeLevelType_to_string(EPrivilegeLevelType::M) == "M");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EPrivilegeLevelType("U") == EPrivilegeLevelType::U);
      EXPECT(string_to_EPrivilegeLevelType("S") == EPrivilegeLevelType::S);
      EXPECT(string_to_EPrivilegeLevelType("H") == EPrivilegeLevelType::H);
      EXPECT(string_to_EPrivilegeLevelType("M") == EPrivilegeLevelType::M);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EPrivilegeLevelType("_"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EPrivilegeLevelType("U", okay) == EPrivilegeLevelType::U);
      EXPECT(okay);
      EXPECT(try_string_to_EPrivilegeLevelType("S", okay) == EPrivilegeLevelType::S);
      EXPECT(okay);
      EXPECT(try_string_to_EPrivilegeLevelType("H", okay) == EPrivilegeLevelType::H);
      EXPECT(okay);
      EXPECT(try_string_to_EPrivilegeLevelType("M", okay) == EPrivilegeLevelType::M);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EPrivilegeLevelType("_", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EMemAttributeImplType" ) {

  SETUP ( "setup EMemAttributeImplType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EMemAttributeImplType_to_string(EMemAttributeImplType::Unpredictable) == "Unpredictable");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EMemAttributeImplType("Unpredictable") == EMemAttributeImplType::Unpredictable);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EMemAttributeImplType("U_predictable"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EMemAttributeImplType("Unpredictable", okay) == EMemAttributeImplType::Unpredictable);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EMemAttributeImplType("U_predictable", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for ESystemOptionType" ) {

  SETUP ( "setup ESystemOptionType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::PrivilegeLevel) == "PrivilegeLevel");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::DisablePaging) == "DisablePaging");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::NoHandler) == "NoHandler");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::NoSkip) == "NoSkip");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::FlatMap) == "FlatMap");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::MatchedHandler) == "MatchedHandler");
      EXPECT(ESystemOptionType_to_string(ESystemOptionType::SkipBootCode) == "SkipBootCode");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_ESystemOptionType("PrivilegeLevel") == ESystemOptionType::PrivilegeLevel);
      EXPECT(string_to_ESystemOptionType("DisablePaging") == ESystemOptionType::DisablePaging);
      EXPECT(string_to_ESystemOptionType("NoHandler") == ESystemOptionType::NoHandler);
      EXPECT(string_to_ESystemOptionType("NoSkip") == ESystemOptionType::NoSkip);
      EXPECT(string_to_ESystemOptionType("FlatMap") == ESystemOptionType::FlatMap);
      EXPECT(string_to_ESystemOptionType("MatchedHandler") == ESystemOptionType::MatchedHandler);
      EXPECT(string_to_ESystemOptionType("SkipBootCode") == ESystemOptionType::SkipBootCode);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_ESystemOptionType("P_ivilegeLevel"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_ESystemOptionType("PrivilegeLevel", okay) == ESystemOptionType::PrivilegeLevel);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("DisablePaging", okay) == ESystemOptionType::DisablePaging);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("NoHandler", okay) == ESystemOptionType::NoHandler);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("NoSkip", okay) == ESystemOptionType::NoSkip);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("FlatMap", okay) == ESystemOptionType::FlatMap);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("MatchedHandler", okay) == ESystemOptionType::MatchedHandler);
      EXPECT(okay);
      EXPECT(try_string_to_ESystemOptionType("SkipBootCode", okay) == ESystemOptionType::SkipBootCode);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_ESystemOptionType("P_ivilegeLevel", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EExceptionClassType" ) {

  SETUP ( "setup EExceptionClassType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::InstrAddrMisaligned) == "InstrAddrMisaligned");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::InstrAccessFault) == "InstrAccessFault");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::IllegalInstr) == "IllegalInstr");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::Breakpoint) == "Breakpoint");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::LoadAddrMisaligned) == "LoadAddrMisaligned");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::LoadAccessFault) == "LoadAccessFault");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::StoreAmoAddrMisaligned) == "StoreAmoAddrMisaligned");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::StoreAmoAccessFault) == "StoreAmoAccessFault");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::EnvCallFromUMode) == "EnvCallFromUMode");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::EnvCallFromSMode) == "EnvCallFromSMode");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::EnvCallFromMMode) == "EnvCallFromMMode");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::InstrPageFault) == "InstrPageFault");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::LoadPageFault) == "LoadPageFault");
      EXPECT(EExceptionClassType_to_string(EExceptionClassType::StoreAmoPageFault) == "StoreAmoPageFault");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EExceptionClassType("InstrAddrMisaligned") == EExceptionClassType::InstrAddrMisaligned);
      EXPECT(string_to_EExceptionClassType("InstrAccessFault") == EExceptionClassType::InstrAccessFault);
      EXPECT(string_to_EExceptionClassType("IllegalInstr") == EExceptionClassType::IllegalInstr);
      EXPECT(string_to_EExceptionClassType("Breakpoint") == EExceptionClassType::Breakpoint);
      EXPECT(string_to_EExceptionClassType("LoadAddrMisaligned") == EExceptionClassType::LoadAddrMisaligned);
      EXPECT(string_to_EExceptionClassType("LoadAccessFault") == EExceptionClassType::LoadAccessFault);
      EXPECT(string_to_EExceptionClassType("StoreAmoAddrMisaligned") == EExceptionClassType::StoreAmoAddrMisaligned);
      EXPECT(string_to_EExceptionClassType("StoreAmoAccessFault") == EExceptionClassType::StoreAmoAccessFault);
      EXPECT(string_to_EExceptionClassType("EnvCallFromUMode") == EExceptionClassType::EnvCallFromUMode);
      EXPECT(string_to_EExceptionClassType("EnvCallFromSMode") == EExceptionClassType::EnvCallFromSMode);
      EXPECT(string_to_EExceptionClassType("EnvCallFromMMode") == EExceptionClassType::EnvCallFromMMode);
      EXPECT(string_to_EExceptionClassType("InstrPageFault") == EExceptionClassType::InstrPageFault);
      EXPECT(string_to_EExceptionClassType("LoadPageFault") == EExceptionClassType::LoadPageFault);
      EXPECT(string_to_EExceptionClassType("StoreAmoPageFault") == EExceptionClassType::StoreAmoPageFault);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EExceptionClassType("I_strAddrMisaligned"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EExceptionClassType("InstrAddrMisaligned", okay) == EExceptionClassType::InstrAddrMisaligned);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("InstrAccessFault", okay) == EExceptionClassType::InstrAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("IllegalInstr", okay) == EExceptionClassType::IllegalInstr);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("Breakpoint", okay) == EExceptionClassType::Breakpoint);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("LoadAddrMisaligned", okay) == EExceptionClassType::LoadAddrMisaligned);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("LoadAccessFault", okay) == EExceptionClassType::LoadAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("StoreAmoAddrMisaligned", okay) == EExceptionClassType::StoreAmoAddrMisaligned);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("StoreAmoAccessFault", okay) == EExceptionClassType::StoreAmoAccessFault);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("EnvCallFromUMode", okay) == EExceptionClassType::EnvCallFromUMode);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("EnvCallFromSMode", okay) == EExceptionClassType::EnvCallFromSMode);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("EnvCallFromMMode", okay) == EExceptionClassType::EnvCallFromMMode);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("InstrPageFault", okay) == EExceptionClassType::InstrPageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("LoadPageFault", okay) == EExceptionClassType::LoadPageFault);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionClassType("StoreAmoPageFault", okay) == EExceptionClassType::StoreAmoPageFault);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EExceptionClassType("I_strAddrMisaligned", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EInstructionGroupType" ) {

  SETUP ( "setup EInstructionGroupType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EInstructionGroupType_to_string(EInstructionGroupType::General) == "General");
      EXPECT(EInstructionGroupType_to_string(EInstructionGroupType::Float) == "Float");
      EXPECT(EInstructionGroupType_to_string(EInstructionGroupType::System) == "System");
      EXPECT(EInstructionGroupType_to_string(EInstructionGroupType::Vector) == "Vector");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EInstructionGroupType("General") == EInstructionGroupType::General);
      EXPECT(string_to_EInstructionGroupType("Float") == EInstructionGroupType::Float);
      EXPECT(string_to_EInstructionGroupType("System") == EInstructionGroupType::System);
      EXPECT(string_to_EInstructionGroupType("Vector") == EInstructionGroupType::Vector);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EInstructionGroupType("G_neral"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EInstructionGroupType("General", okay) == EInstructionGroupType::General);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionGroupType("Float", okay) == EInstructionGroupType::Float);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionGroupType("System", okay) == EInstructionGroupType::System);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionGroupType("Vector", okay) == EInstructionGroupType::Vector);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EInstructionGroupType("G_neral", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EInstructionExtensionType" ) {

  SETUP ( "setup EInstructionExtensionType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::Default) == "Default");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32I) == "RV32I");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64I) == "RV64I");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32A) == "RV32A");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64A) == "RV64A");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32M) == "RV32M");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64M) == "RV64M");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32F) == "RV32F");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64F) == "RV64F");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32D) == "RV32D");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64D) == "RV64D");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32Q) == "RV32Q");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64Q) == "RV64Q");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::Zicsr) == "Zicsr");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::Zifencei) == "Zifencei");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32C) == "RV32C");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64C) == "RV64C");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV128C) == "RV128C");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64Priv) == "RV64Priv");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV32H) == "RV32H");
      EXPECT(EInstructionExtensionType_to_string(EInstructionExtensionType::RV64H) == "RV64H");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EInstructionExtensionType("Default") == EInstructionExtensionType::Default);
      EXPECT(string_to_EInstructionExtensionType("RV32I") == EInstructionExtensionType::RV32I);
      EXPECT(string_to_EInstructionExtensionType("RV64I") == EInstructionExtensionType::RV64I);
      EXPECT(string_to_EInstructionExtensionType("RV32A") == EInstructionExtensionType::RV32A);
      EXPECT(string_to_EInstructionExtensionType("RV64A") == EInstructionExtensionType::RV64A);
      EXPECT(string_to_EInstructionExtensionType("RV32M") == EInstructionExtensionType::RV32M);
      EXPECT(string_to_EInstructionExtensionType("RV64M") == EInstructionExtensionType::RV64M);
      EXPECT(string_to_EInstructionExtensionType("RV32F") == EInstructionExtensionType::RV32F);
      EXPECT(string_to_EInstructionExtensionType("RV64F") == EInstructionExtensionType::RV64F);
      EXPECT(string_to_EInstructionExtensionType("RV32D") == EInstructionExtensionType::RV32D);
      EXPECT(string_to_EInstructionExtensionType("RV64D") == EInstructionExtensionType::RV64D);
      EXPECT(string_to_EInstructionExtensionType("RV32Q") == EInstructionExtensionType::RV32Q);
      EXPECT(string_to_EInstructionExtensionType("RV64Q") == EInstructionExtensionType::RV64Q);
      EXPECT(string_to_EInstructionExtensionType("Zicsr") == EInstructionExtensionType::Zicsr);
      EXPECT(string_to_EInstructionExtensionType("Zifencei") == EInstructionExtensionType::Zifencei);
      EXPECT(string_to_EInstructionExtensionType("RV32C") == EInstructionExtensionType::RV32C);
      EXPECT(string_to_EInstructionExtensionType("RV64C") == EInstructionExtensionType::RV64C);
      EXPECT(string_to_EInstructionExtensionType("RV128C") == EInstructionExtensionType::RV128C);
      EXPECT(string_to_EInstructionExtensionType("RV64Priv") == EInstructionExtensionType::RV64Priv);
      EXPECT(string_to_EInstructionExtensionType("RV32H") == EInstructionExtensionType::RV32H);
      EXPECT(string_to_EInstructionExtensionType("RV64H") == EInstructionExtensionType::RV64H);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EInstructionExtensionType("D_fault"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EInstructionExtensionType("Default", okay) == EInstructionExtensionType::Default);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32I", okay) == EInstructionExtensionType::RV32I);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64I", okay) == EInstructionExtensionType::RV64I);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32A", okay) == EInstructionExtensionType::RV32A);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64A", okay) == EInstructionExtensionType::RV64A);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32M", okay) == EInstructionExtensionType::RV32M);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64M", okay) == EInstructionExtensionType::RV64M);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32F", okay) == EInstructionExtensionType::RV32F);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64F", okay) == EInstructionExtensionType::RV64F);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32D", okay) == EInstructionExtensionType::RV32D);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64D", okay) == EInstructionExtensionType::RV64D);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32Q", okay) == EInstructionExtensionType::RV32Q);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64Q", okay) == EInstructionExtensionType::RV64Q);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("Zicsr", okay) == EInstructionExtensionType::Zicsr);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("Zifencei", okay) == EInstructionExtensionType::Zifencei);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32C", okay) == EInstructionExtensionType::RV32C);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64C", okay) == EInstructionExtensionType::RV64C);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV128C", okay) == EInstructionExtensionType::RV128C);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64Priv", okay) == EInstructionExtensionType::RV64Priv);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV32H", okay) == EInstructionExtensionType::RV32H);
      EXPECT(okay);
      EXPECT(try_string_to_EInstructionExtensionType("RV64H", okay) == EInstructionExtensionType::RV64H);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EInstructionExtensionType("D_fault", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EMemOrderingType" ) {

  SETUP ( "setup EMemOrderingType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::Init) == "Init");
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::Atomic) == "Atomic");
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::AtomicRW) == "AtomicRW");
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::Ordered) == "Ordered");
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::LimitedOrdered) == "LimitedOrdered");
      EXPECT(EMemOrderingType_to_string(EMemOrderingType::OrderedRW) == "OrderedRW");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EMemOrderingType("Init") == EMemOrderingType::Init);
      EXPECT(string_to_EMemOrderingType("Atomic") == EMemOrderingType::Atomic);
      EXPECT(string_to_EMemOrderingType("AtomicRW") == EMemOrderingType::AtomicRW);
      EXPECT(string_to_EMemOrderingType("Ordered") == EMemOrderingType::Ordered);
      EXPECT(string_to_EMemOrderingType("LimitedOrdered") == EMemOrderingType::LimitedOrdered);
      EXPECT(string_to_EMemOrderingType("OrderedRW") == EMemOrderingType::OrderedRW);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EMemOrderingType("I_it"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EMemOrderingType("Init", okay) == EMemOrderingType::Init);
      EXPECT(okay);
      EXPECT(try_string_to_EMemOrderingType("Atomic", okay) == EMemOrderingType::Atomic);
      EXPECT(okay);
      EXPECT(try_string_to_EMemOrderingType("AtomicRW", okay) == EMemOrderingType::AtomicRW);
      EXPECT(okay);
      EXPECT(try_string_to_EMemOrderingType("Ordered", okay) == EMemOrderingType::Ordered);
      EXPECT(okay);
      EXPECT(try_string_to_EMemOrderingType("LimitedOrdered", okay) == EMemOrderingType::LimitedOrdered);
      EXPECT(okay);
      EXPECT(try_string_to_EMemOrderingType("OrderedRW", okay) == EMemOrderingType::OrderedRW);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EMemOrderingType("I_it", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EExceptionVectorType" ) {

  SETUP ( "setup EExceptionVectorType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EExceptionVectorType_to_string(EExceptionVectorType::DefaultMachineModeVector) == "DefaultMachineModeVector");
      EXPECT(EExceptionVectorType_to_string(EExceptionVectorType::DefaultSupervisorModeVector) == "DefaultSupervisorModeVector");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EExceptionVectorType("DefaultMachineModeVector") == EExceptionVectorType::DefaultMachineModeVector);
      EXPECT(string_to_EExceptionVectorType("DefaultSupervisorModeVector") == EExceptionVectorType::DefaultSupervisorModeVector);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EExceptionVectorType("D_faultMachineModeVector"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EExceptionVectorType("DefaultMachineModeVector", okay) == EExceptionVectorType::DefaultMachineModeVector);
      EXPECT(okay);
      EXPECT(try_string_to_EExceptionVectorType("DefaultSupervisorModeVector", okay) == EExceptionVectorType::DefaultSupervisorModeVector);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EExceptionVectorType("D_faultMachineModeVector", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for ESystemOpType" ) {

  SETUP ( "setup ESystemOpType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(ESystemOpType_to_string(ESystemOpType::None) == "None");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_ESystemOpType("None") == ESystemOpType::None);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_ESystemOpType("N_ne"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_ESystemOpType("None", okay) == ESystemOpType::None);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_ESystemOpType("N_ne", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EMemoryAttributeType" ) {

  SETUP ( "setup EMemoryAttributeType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EMemoryAttributeType_to_string(EMemoryAttributeType::Device) == "Device");
      EXPECT(EMemoryAttributeType_to_string(EMemoryAttributeType::NormalCacheable) == "NormalCacheable");
      EXPECT(EMemoryAttributeType_to_string(EMemoryAttributeType::NormalNonCacheable) == "NormalNonCacheable");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EMemoryAttributeType("Device") == EMemoryAttributeType::Device);
      EXPECT(string_to_EMemoryAttributeType("NormalCacheable") == EMemoryAttributeType::NormalCacheable);
      EXPECT(string_to_EMemoryAttributeType("NormalNonCacheable") == EMemoryAttributeType::NormalNonCacheable);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EMemoryAttributeType("D_vice"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EMemoryAttributeType("Device", okay) == EMemoryAttributeType::Device);
      EXPECT(okay);
      EXPECT(try_string_to_EMemoryAttributeType("NormalCacheable", okay) == EMemoryAttributeType::NormalCacheable);
      EXPECT(okay);
      EXPECT(try_string_to_EMemoryAttributeType("NormalNonCacheable", okay) == EMemoryAttributeType::NormalNonCacheable);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EMemoryAttributeType("D_vice", okay);
      EXPECT(!okay);
    }
  }
},


CASE( "tests for EVmInfoBoolType" ) {

  SETUP ( "setup EVmInfoBoolType" )  {

    SECTION( "test enum to string conversion" ) {
      EXPECT(EVmInfoBoolType_to_string(EVmInfoBoolType::MODE) == "MODE");
      EXPECT(EVmInfoBoolType_to_string(EVmInfoBoolType::MPRV) == "MPRV");
      EXPECT(EVmInfoBoolType_to_string(EVmInfoBoolType::TVM) == "TVM");
    }

    SECTION( "test string to enum conversion" ) {
      EXPECT(string_to_EVmInfoBoolType("MODE") == EVmInfoBoolType::MODE);
      EXPECT(string_to_EVmInfoBoolType("MPRV") == EVmInfoBoolType::MPRV);
      EXPECT(string_to_EVmInfoBoolType("TVM") == EVmInfoBoolType::TVM);
    }

    SECTION( "test string to enum conversion with non-matching string" ) {
      EXPECT_THROWS_AS(string_to_EVmInfoBoolType("M_DE"), EnumTypeError);
    }

    SECTION( "test non-throwing string to enum conversion" ) {
      bool okay = false;
      EXPECT(try_string_to_EVmInfoBoolType("MODE", okay) == EVmInfoBoolType::MODE);
      EXPECT(okay);
      EXPECT(try_string_to_EVmInfoBoolType("MPRV", okay) == EVmInfoBoolType::MPRV);
      EXPECT(okay);
      EXPECT(try_string_to_EVmInfoBoolType("TVM", okay) == EVmInfoBoolType::TVM);
      EXPECT(okay);
    }

    SECTION( "test non-throwing string to enum conversion with non-matching string" ) {
      bool okay = false;
      try_string_to_EVmInfoBoolType("M_DE", okay);
      EXPECT(!okay);
    }
  }
},

};

int main(int argc, char* argv[])
{
  Logger::Initialize();
  int ret = lest::run(specification, argc, argv);
  Logger::Destroy();
  return ret;
}
